import java.util.Scanner;

public class BankerAlgorithm {
    private static final int PROCESS_COUNT = 5; // 进程数量
    private static final int RESOURCE_COUNT = 3; // 资源种类数量

    // 可用资源数量
    private int[] available = {3, 3, 2};
    // 最大需求矩阵
    private int[][] max = {
            {7, 5, 3},
            {3, 2, 2},
            {9, 0, 2},
            {2, 2, 2},
            {4, 3, 3}
    };
    // 分配矩阵
    private int[][] allocation = {
            {0, 1, 0},
            {2, 0, 0},
            {3, 0, 2},
            {2, 1, 1},
            {0, 0, 2}
    };
    // 需求矩阵
    private int[][] need;
    // 进程状态
    private String[] processStatus;

    public BankerAlgorithm() {
        // 初始化need矩阵
        need = new int[PROCESS_COUNT][RESOURCE_COUNT];
        for (int i = 0; i < PROCESS_COUNT; i++) {
            for (int j = 0; j < RESOURCE_COUNT; j++) {
                need[i][j] = max[i][j] - allocation[i][j];
            }
        }

        // 初始化进程状态
        processStatus = new String[PROCESS_COUNT];
        for (int i = 0; i < PROCESS_COUNT; i++) {
            processStatus[i] = "Ready";
        }
    }

    // 显示当前资源分配情况
    public void displayCurrentState() {
        System.out.println("当前资源分配情况：");
        System.out.println("进程\t最大需求\t已分配资源\t需求资源\t状态");
        for (int i = 0; i < PROCESS_COUNT; i++) {
            System.out.print("P" + i + "\t");
            for (int j = 0; j < RESOURCE_COUNT; j++) {
                System.out.print(max[i][j] + " ");
            }
            System.out.print("\t");
            for (int j = 0; j < RESOURCE_COUNT; j++) {
                System.out.print(allocation[i][j] + " ");
            }
            System.out.print("\t");
            for (int j = 0; j < RESOURCE_COUNT; j++) {
                System.out.print(need[i][j] + " ");
            }
            System.out.print("\t");
            System.out.println(processStatus[i]);
        }
        System.out.print("可用资源：");
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            System.out.print(available[i] + " ");
        }
        System.out.println();
    }

    // 安全性检查
    public boolean isSafe() {
        int[] work = available.clone();
        boolean[] finish = new boolean[PROCESS_COUNT];
        int[] safeSequence = new int[PROCESS_COUNT];
        int count = 0;

        while (count < PROCESS_COUNT) {
            boolean found = false;
            for (int i = 0; i < PROCESS_COUNT; i++) {
                if (!finish[i]) {
                    boolean canAllocate = true;
                    for (int j = 0; j < RESOURCE_COUNT; j++) {
                        if (need[i][j] > work[j]) {
                            canAllocate = false;
                            break;
                        }
                    }
                    if (canAllocate) {
                        for (int j = 0; j < RESOURCE_COUNT; j++) {
                            work[j] += allocation[i][j];
                        }
                        safeSequence[count] = i;
                        count++;
                        finish[i] = true;
                        found = true;
                    }
                }
            }
            if (!found) {
                break;
            }
        }

        if (count == PROCESS_COUNT) {
            System.out.print("安全序列：");
            for (int i = 0; i < PROCESS_COUNT; i++) {
                System.out.print("P" + safeSequence[i] + " ");
            }
            System.out.println();
            return true;
        }
        return false;
    }

    // 申请资源
    public void requestResources(int processId, int[] request) {
        if (processId < 0 || processId >= PROCESS_COUNT) {
            System.out.println("进程ID无效！");
            return;
        }

        // 检查请求资源是否为负数
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            if (request[i] < 0) {
                System.out.println("请求资源不能为负数！");
                return;
            }
        }

        // 检查申请资源是否超过需求
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            if (request[i] > need[processId][i]) {
                System.out.println("进程P" + processId + "申请的资源超过最大需求！");
                return;
            }
        }

        // 检查申请资源是否超过可用资源
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            if (request[i] > available[i]) {
                System.out.println("进程P" + processId + "申请的资源超过可用资源！");
                return;
            }
        }

        // 尝试分配资源
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            available[i] -= request[i];
            allocation[processId][i] += request[i];
            need[processId][i] -= request[i];
        }

        // 检查安全性
        if (isSafe()) {
            System.out.println("资源分配成功，系统安全！");
            // 检查进程是否完成
            boolean finished = true;
            for (int i = 0; i < RESOURCE_COUNT; i++) {
                if (need[processId][i] != 0) {
                    finished = false;
                    break;
                }
            }
            if (finished) {
                processStatus[processId] = "Finished";
                // 释放资源
                for (int i = 0; i < RESOURCE_COUNT; i++) {
                    available[i] += allocation[processId][i];
                    allocation[processId][i] = 0;
                }
                System.out.println("进程P" + processId + "已完成并释放所有资源！");
            }
        } else {
            // 恢复原状
            for (int i = 0; i < RESOURCE_COUNT; i++) {
                available[i] += request[i];
                allocation[processId][i] -= request[i];
                need[processId][i] += request[i];
            }
            System.out.println("资源分配失败，系统不安全！");
        }
    }

    // 释放资源
    public void releaseResources(int processId, int[] release) {
        if (processId < 0 || processId >= PROCESS_COUNT) {
            System.out.println("进程ID无效！");
            return;
        }

        // 检查释放资源是否为负数
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            if (release[i] < 0) {
                System.out.println("释放资源不能为负数！");
                return;
            }
        }

        // 检查释放资源是否超过已分配资源
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            if (release[i] > allocation[processId][i]) {
                System.out.println("进程P" + processId + "释放的资源超过已分配资源！");
                return;
            }
        }

        // 释放资源
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            available[i] += release[i];
            allocation[processId][i] -= release[i];
            need[processId][i] += release[i];
        }

        System.out.println("资源释放成功！");

        // 检查进程是否可以完成
        boolean canFinish = true;
        for (int i = 0; i < RESOURCE_COUNT; i++) {
            if (need[processId][i] > available[i]) {
                canFinish = false;
                break;
            }
        }
        if (canFinish) {
            System.out.println("进程P" + processId + "现在可以完成！");
        }
    }

    public static void main(String[] args) {
        BankerAlgorithm bankerAlgorithm = new BankerAlgorithm();
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("\n1. 显示当前资源分配情况");
            System.out.println("2. 申请资源");
            System.out.println("3. 释放资源");
            System.out.println("4. 检查系统安全性");
            System.out.println("5. 退出");
            System.out.print("请输入操作选项：");
            int choice = scanner.nextInt();

            switch (choice) {
                case 1:
                    bankerAlgorithm.displayCurrentState();
                    break;
                case 2:
                    System.out.print("请输入申请资源的进程ID(0-" + (PROCESS_COUNT-1) + ")：");
                    int processId = scanner.nextInt();
                    int[] request = new int[RESOURCE_COUNT];
                    System.out.println("请输入申请的资源数量（" + RESOURCE_COUNT + "种资源）：");
                    for (int i = 0; i < RESOURCE_COUNT; i++) {
                        request[i] = scanner.nextInt();
                    }
                    bankerAlgorithm.requestResources(processId, request);
                    break;
                case 3:
                    System.out.print("请输入释放资源的进程ID(0-" + (PROCESS_COUNT-1) + ")：");
                    processId = scanner.nextInt();
                    int[] release = new int[RESOURCE_COUNT];
                    System.out.println("请输入释放的资源数量（" + RESOURCE_COUNT + "种资源）：");
                    for (int i = 0; i < RESOURCE_COUNT; i++) {
                        release[i] = scanner.nextInt();
                    }
                    bankerAlgorithm.releaseResources(processId, release);
                    break;
                case 4:
                    if (bankerAlgorithm.isSafe()) {
                        System.out.println("系统当前处于安全状态！");
                    } else {
                        System.out.println("系统当前处于不安全状态！");
                    }
                    break;
                case 5:
                    System.out.println("退出程序！");
                    scanner.close();
                    return;
                default:
                    System.out.println("无效选项！");
            }
        }
    }
}